$NOMOD51
$INCLUDE (STC60S2.MCU)
; COMPILE WITH ASEM
; >ASEM.EXE c:\PROGS\MAIN.ASM /INCLUDES:C:\ASEM5113\MCU

;Main Program
;INIT: LCD (DS18B20)
;SPLASH 3S

; Pin Def'n
LCD_RS      BIT     P2.0
LCD_RW      BIT     P2.1
LCD_E       BIT     P2.2

;===USED IN emu8051===
;;LCD_RS      BIT     P3.6
;;LCD_RW      BIT     P3.5
;;LCD_E       BIT     P3.7
;;DAT_PORT    EQU     P1
;=====================

DAT_PORT    EQU     P0
LED_PIN	    BIT	  P2.4



; HEAD
ORG 0000H
LJMP INIT



; LCD1602 Driver
;---------------------LCD1602 init------------------------------
INIT_LCD:     ACALL   CLS_LCD
              MOV     DAT_PORT,#02H       ; 光标复位，光标返回到地址00H
              ACALL   WR_LCD_CMD
              MOV     DAT_PORT,#38H       ; 8位数据接口 5*7 点阵
              ACALL   WR_LCD_CMD
              MOV     DAT_PORT,#06H       ; 光标右移，文字不移
              ACALL   WR_LCD_CMD
              MOV     DAT_PORT,#0CH       ; 不显示光标， 光标不闪
              ACALL   WR_LCD_CMD
              RET

;---------------------发送数据给LCD------------------------------
WR_LCD_DAT:   MOV     DAT_PORT,A
              SETB    LCD_RS               ;选择数据寄存器
			  NOP
			  NOP
              CLR     LCD_RW               ;低电平，写操作
			  NOP
			  NOP
              CLR     LCD_E                ;电平由高到低，执行命令
			  NOP
			  NOP
			  NOP
			  NOP
              ACALL   BUSY_LCD             ;判断是否忙
              SETB    LCD_E
              RET
;---------------------发送指令给LCD------------------------------
WR_LCD_CMD:   CLR     LCD_RS                ;选择指令寄存器
              CLR     LCD_RW
			  NOP
			  NOP
              CLR     LCD_E
			  NOP
			  NOP
			  NOP
			  NOP
              ACALL   BUSY_LCD
              SETB    LCD_E
              RET
;---------------------判断LCD是否忙------------------------------
BUSY_LCD:     MOV     DAT_PORT,#0FFH
              CLR     LCD_RS               ;选择指令寄存器
              SETB    LCD_RW               ;高电平，读操作
			  NOP
			  NOP
              CLR     LCD_E                ;电平由高到低，执行命令
              NOP                          ;不可少
			  NOP
              SETB    LCD_E
			  NOP
			  NOP
              JB      DAT_PORT.7,BUSY_LCD
              RET
;---------------------Clear Screen-----------------------------
CLS_LCD:      MOV     DAT_PORT,#01H
              ACALL   WR_LCD_CMD
			  NOP
			  NOP
              RET
;==============================================================

; ADC Functions
; Uses stack
INIT_ADC:     MOV P1ASF, #0FH; (00001111B) - P1.0, P1.1, P1.2, P1.3 as ADC input ports
			  MOV ADC_CONTR, #0E0H    ; (11100xxx(000)) 
			  NOP
			  NOP
			  NOP
			  NOP
			  PUSH ACC
			  MOV A, AUXR1
			  ANL A, #0FBH   ;(11111011b) ADRJ = 0
			  MOV AUXR1, A
			  POP ACC
			  RET
			  
; Start ADC Convert
; Usage:
; A - 0: P1.0
;   - 1: P1.1
;   - 2: P1.2
;   - 3: P1.3
START_CVRT_ADC_SINGLE:
			  ADD A, #0E8H   ;(11101000B)
			  MOV ADC_CONTR, A
			  NOP
			  NOP
			  NOP
			  NOP
			  RET
			  
; Display adc result to LCD (8 bit Mode)
; MODE:
; Input: R6 - ADC_RES
DISP_ADC_8:
			  

	
; Test if ADC result comes out
; and put it in when result comes
; R7 -- ADC_RESL
; R6 -- ADC_RES
QUERY_ADC:    
			  MOV A, ADC_CONTR
			  ANL A, #10H    ; (00010000b) -> Detect ADC_FLAG, A=0 when ADCFLAG=0(Not complete)
			  JZ  QA_A       ; exit
			  ANL ADC_CONTR, #0EFH   ; (11101111b) -> Clear ADC FLAG
			  MOV R7, ADC_RESL
			  MOV R6, ADC_RES
			  ;; SAVE LATEST ADC RESULTS 
			  MOV A, LADCPORT
			  JZ QA_P10
			  DEC A
			  JZ QA_P11
			  DEC A
			  JZ QA_P12
			  DEC A
			  JZ QA_P13
QA_P10:		  MOV LADCRSL_P10, R7
			  MOV LADCRS_P10, R6
			  RET
QA_P11: 	  MOV LADCRSL_P11, R7
			  MOV LADCRS_P11, R6
			  RET
QA_P12:		  MOV LADCRSL_P12, R7
			  MOV LADCRS_P12, R6
			  RET
QA_P13:		  MOV LADCRSL_P13, R7
			  MOV LADCRS_P13, R6
QA_A:		  RET

; =====Constants & Heap Allocation=====
; String Format
; START_PTR | STRING CONTENT | 00H (String Ending Flag)
HelloStrU: db 00H,"WWWSky SolarSys", 00H
HelloStrL: db 40H," Rev 0.1 alpha", 00H

; Heap & Stack
; Total mem allocation:
; -> 30H~7FH (80 bytes)
;    30H~4FH (32 bytes) -- Stack (Max 16 calls if no other pushes)
STACK_START_PTR   equ   30H
;    50H~53H (4 bytes) -- Temp 32-bit Unsigned A (Little Endian)
TMP32A   EQU   50H
;    54H~57H (4 bytes) -- B
TMP32B   EQU   54H
;    58H~5BH (4 bytes) -- Results A
RES32A   EQU   58H
;    5CH~5FH (4 bytes) -- Variable A
VARA     EQU   5CH
VARA_1   EQU   5CH
VARA_2   EQU   5DH
VARA_3   EQU   5EH
VARA_4   EQU   5FH
;    60H~63H (4 bytes) -- Variable B
VARB     EQU   60H
VARB_1   EQU   60H
VARB_2   EQU   61H
VARB_3   EQU   62H
VARB_4   EQU   63H
;	 64H~67H (4 bytes) -- char tmp[4]
TMP8A    EQU   64H
TMP8B    EQU   65H
TMP8C    EQU   66H
TMP8D    EQU   67H
;    68H~70H (9 bytes) -- Latest adc stats
LADCRS_P10   EQU   68H
LADCRSL_P10  EQU   69H
LADCRS_P11   EQU   6AH
LADCRSL_P11  EQU   6BH
LADCRS_P12   EQU   6CH
LADCRSL_P12  EQU   6DH
LADCRS_P13   EQU   6EH
LADCRSL_P13  EQU   6FH
; LADCPORT  - 0: P1.0
;   		- 1: P1.1
;  			- 2: P1.2
;  		 	- 3: P1.3
LADCPORT     EQU   70H

; Import maths utility
$INCLUDE (maths.asm)

; UI Related
; MODE: BATT<->SOLAR<->STAT	  
BattStrU: db 00H,"BATT:", 00H
BattStrLDg: db 40H,"Discharge|", 00H
BattStrLFg: db 40H,"Floatchrg|", 00H
BattStrLQg: db 40H,"Quickchrg|", 00H


; FSM Based Task Scheduler
; R7 to save current state


; STATES:
; ProcessInput
; CollectADC
; AdjustChargeStatus
; FlushDisplay

INIT:   MOV   SP, #STACK_START_PTR ; Set Stack Pointer
		LCALL INIT_LCD
		MOV   DPTR, #HelloStrL
		LCALL DispStr
		MOV   DPTR, #HelloStrU
		LCALL DispStr
		
		
		AJMP  MAIN
	   
MAIN:   
		
		
		
		; Test DispInt16I
		MOV R7, #0DDH
		MOV R6, #0C7H
		MOV R4, #00H
		LCALL DispInt16I
		; expected '56775'
		; Test DispDec16I
		MOV R7, #0FCH
		MOV R6, #0H
		MOV R4, #40H
		MOV R0, #08H
		LCALL DispDec16I
		;Expect 98437500
		
		
	   AJMP  START

START: SETB LED_PIN
       ACALL DELAY
       CLR LED_PIN
	   ACALL DELAY
	   JMP START
	
DELAY: MOV R0, 0FFh
       MOV R1, 0FFh
	   
ASEG:  DJNZ R0,ASEG
	   MOV R0, 0FFh
	   DJNZ R1,ASEG
	   RET

	   
END